﻿using System;
using System.Reflection;
using Moki;

namespace Moki.Core
{
    /// <summary>
    /// Encapsulates stub implementatation, return value or exception. Invokes callback or events when stub is used.
    /// </summary>
    internal class StubResult
    {
        public Delegate Implementation { get; set; }
        public bool ThrowsException { get; set; }
        public object ReturnValue { get; set; }
        public Action<Arguments> CallBackAction { get; set; }
        public Delegate Event { get; set; }
        public object[] EventArgs { get; set; }

        public void Invoke(Arguments arguments)
        {
            try
            {
                if (Implementation != null)
                {
                    if (ThrowsException)
                        ReturnValue = Implementation.DynamicInvoke(null);

                    if (arguments.Count == 0)
                        ReturnValue = Implementation.DynamicInvoke(null);
                    else
                        ReturnValue = Implementation.DynamicInvoke(arguments);
                }
            }
            catch (TargetInvocationException ex)
            {
                throw ex.InnerException;
            }
            finally
            {
                if (CallBackAction != null)
                    CallBackAction(arguments);

                if (Event != null)
                    Event.DynamicInvoke(EventArgs);
            }
        }
    }
}
